package com.dy.design_pattern_study.bridge_pattern.dome2;

import com.dy.design_pattern_study.bridge_pattern.dome2.impl.*;

/**
 * @CreateBy zhangdingyi
 * @Date 2023-04-18
 * @Content 桥接模式（Bridge），将抽象部分与它的实现部分分离，使它们都可以独立地变化
 * 又称 柄体(Handle and Body)模式或接口(interface)模式
 * <p>
 * 什么叫抽象与它的实现分离，
 * 这并不是说，让抽象类与其派生类分离，因为这没有任何意义。
 * 实现指的是抽象类和它的派生类用来实现自己的对象
 * 简单的说，抽象与实现的分离就是，抽象接口的互相调用，并不会对应具体的实体类有影响，仅会对其过程有影响
 * 这里可以把抽象当成 数学运算符号，而实体就是具体的数值，不同的数值仅会导致结果的不同，而运算符号
 * 又不会对 具体的数值产生影响，仅会对结果产生印象
 * <p>
 * 简单的说这个就是
 * 将两个角色之间的继承关系改为聚合关系，就是将它们之间的强关联改换成为弱关联
 * <p>
 * 再简单一点就是
 * 某个功能有多种继承关系，这里把多种继承关系 变成 非继承的聚合或者组合关系
 * 手机：有手机品牌、手机软件、手机系统
 * 电脑：有电脑品牌、电脑软件、电脑系统
 * 水壶：有水壶品牌、水壶类型（电热版、火烧版）
 */
public class client {
    /*
        在什么时候会使用到桥接模式？
        在软件系统中，某些类型由于自身的逻辑，它具有 两个或多个维度的变化 ，那么如何应对这种“多维度的变化”？
        如何利用面向对象的技术来使得该类型能够轻松的沿着 多个方向进行变化，而又不引入额外的复杂度？

        1.某个类型有多个纬度的变化且不想引入额外的复杂度时，需要用到
     */

    public static void main(String[] args) {
        System.out.println("A 品牌手机运行");
        HandsetBrand ab;
        ab = new HandsetBrandA();

        //这里的话，有点像策略模式，传入不同的策略可以得出不同的结果
        //设置软件 --游戏
        ab.SetHandsetSoft(new HandsetGame());
        ab.runHandset();

        //设置软件 --通讯地址
        ab.SetHandsetSoft(new HandsetAddressList());
        ab.runHandset();

        System.out.println("--------------------------------");
        System.out.println("B 品牌手机运行");

        ab = new HandsetBrandB();

        //设置软件 --游戏
        ab.SetHandsetSoft(new HandsetGame());
        ab.runHandset();

        //设置软件 --通讯地址
        ab.SetHandsetSoft(new HandsetAddressList());
        ab.runHandset();

        /*
            上面的话，实际就是把相同的属性抽取出来当成一个独立的功能
            然后再组合到主对象中（手机品牌），然后就是不同手机都有相同的功能
            如有拓展，则仅需要新增 类即可，具体的调用由客户端进行组装
         */

        System.out.println("--------------------------------");
        System.out.println("C 品牌手机运行");

        ab = new HandsetBrandC();

        //设置软件 --游戏
        ab.SetHandsetSoft(new HandsetGame());
        ab.runHandset();

        //设置软件 --通讯地址
        ab.SetHandsetSoft(new HandsetAddressList());
        ab.runHandset();

        //设置软件 --MP3
        ab.SetHandsetSoft(new HandsetMP3());
        ab.runHandset();

    }
}
